// 条件编译：仅在 APP-PLUS 平台（5+ App）下执行
// #ifdef APP-PLUS
const LogCat = {
  // 获取主Activity上下文
  main: plus.android.runtimeMainActivity(),

  // 导入Android原生类
  Environment: plus.android.importClass('android.os.Environment'),
  StatFs: plus.android.importClass('android.os.StatFs'),
  BufferedWriter: plus.android.importClass('java.io.BufferedWriter'),
  BufferedReader: plus.android.importClass('java.io.BufferedReader'),
  File: plus.android.importClass('java.io.File'),
  FileOutputStream: plus.android.importClass('java.io.FileOutputStream'),
  FileInputStream: plus.android.importClass('java.io.FileInputStream'),
  OutputStreamWriter: plus.android.importClass('java.io.OutputStreamWriter'),
  InputStreamReader: plus.android.importClass('java.io.InputStreamReader'),
  Handler: plus.android.importClass('android.os.Handler'),
  Runnable: plus.android.importClass('java.lang.Runnable'),

  // 日志存储路径
  LogPath: '',

  logs: [],

  max: 200,

  isFlushing: false,

  timer: null,

  /**
   * 初始化日志存储路径
   * 优先使用外部存储，不可用时回退到内部存储
   */
  init: function () {
    if (
      this.Environment.MEDIA_MOUNTED ||
      !this.Environment.isExternalStorageRemovable()
    ) {
      this.LogPath = this.main.getExternalFilesDir(null).getPath() + '/logs'
    } else {
      this.LogPath = this.main.getFilesDir().getPath() + '/logs'
    }
    console.log('日志文件存放路径=>', this.LogPath)
    if (this.timer) {
      clearInterval(this.timer)
    }
    this.timer = setInterval(() => {
      this.flushLogs()
    }, 60 * 1000)
  },

  flushLogs: function() {
    if (this.logs.length == 0 || this.isFlushing) return
    const writeLogs = [...this.logs]
    this.logs = []
    this.isFlushing = true
    const date = writeLogs[0].date
    const str = writeLogs.reduce((pre, curr) => {
      return pre + `\n${curr.datetime}: ${curr.msg}\n`
    }, '')

    this.writeLog(date, str)
  },

  /**
   * 将参数转换为字符串
   * @param {...any} args - 任意数量的参数
   * @returns {string} 拼接后的字符串
   */
  argsToString: function (...args) {
    return args
      .map(arg => (typeof arg === 'object' ? JSON.stringify(arg) : String(arg)))
      .join(',')
  },

  writeAsyncLog: function(...args) {
    const date = getTime('YYYY-MM-DD') // 获取当前日期
    const datetime = getTime() // 获取完整的时间格式
    const msg = this.argsToString(...args) // 转换参数为字符串
    this.logs.push({date, datetime, msg})

    if (this.logs.length > this.max) {
      this.logs = this.logs.slice(-this.max)
    }
    
  },

  /**
   * 写入日志到文件
   * @param {...any} args - 要记录的日志内容
   */
  writeLog: function (date, content) {
    // const date = getTime('YYYY-MM-DD') // 获取当前日期
    // const datetime = getTime() // 获取完整的时间格式
    // const msg = this.argsToString(...args) // 转换参数为字符串

    // 按日期分割日志文件
    const filePath = this.LogPath + '/log_' + date + '.txt'
    // const content = `\n${datetime}: ${msg}\n` // 日志内容格式

    // 确保日志目录存在
    let file = new this.File(this.LogPath)
    if (!file.exists()) {
      file.mkdirs() // 递归创建目录
    }

    // 使用缓冲流写入文件
    let fos = null
    let bw = null
    try {
      fos = new this.FileOutputStream(filePath, true) // true表示追加模式
      bw = new this.BufferedWriter(new this.OutputStreamWriter(fos))
      bw.append(content) // 追加内容
    } catch (e) {
      console.log('写入日志失败=>', e)
    } finally {
      try {
        if (bw != null) bw.close() // 关闭流
        if (fos != null) fos.close()
      } catch (closeEx) {
        console.log('关闭流失败=>', closeEx)
      } finally {
        this.isFlushing = false
      }
    }
    this.deleteOldLogFiles()
  },

  // 删除超过一定数量的旧日志文件
  deleteOldLogFiles: function (maxFileCount = 15) {
    let logFiles = this.getLogFileList()
    // 按照最后修改时间排序
    logFiles.sort(function (a, b) {
      return b.updateTime - a.updateTime
    })
    console.log('总日志文件=>', logFiles)
    if (logFiles.length > maxFileCount) {
      for (let i = maxFileCount; i < logFiles.length; i++) {
        this.removeLogFile(logFiles[i].filePath)
      }
    }
  },

  /**
   * 删除指定日志文件
   * @param {string} filePath - 要删除的文件路径
   */
  removeLogFile: function (filePath) {
    const file = new this.File(filePath)
    const fos = new this.FileOutputStream(filePath, true)
    fos.close()
    file.delete()
    console.log('删除日志文件=>', filePath)
  },

  /**
   * 删除所有日志文件
   */
  removeAllLogFile: function () {
    const logFiles = this.getLogFileList()
    for (let i = 0; i < logFiles.length; i++) {
      this.removeLogFile(logFiles[i].filePath)
    }
  },

  /**
   * 获取日志文件列表
   * @returns {Array} 返回包含文件名和路径的对象数组
   */
  getLogFileList: function () {
    const list = []
    const file = new this.File(this.LogPath)
    const tempList = file.listFiles()

    for (let i = 0; i < tempList.length; i++) {
      list.push({
        index: i,
        name: tempList[i].getName(),
        filePath: tempList[i].getPath(),
        size: tempList[i].length(),
        updateTime: tempList[i].lastModified()
      })
    }

    return list
  },

  /**
   * 读取日志文件内容
   * @param {string} filePath - 文件路径
   * @returns {Array} 按行分割的日志内容数组
   */
  readLog: function (filePath) {
    const charset = 'utf-8'
    let file = new this.File(filePath)
    let list = []

    try {
      if (!file.exists()) return list

      let inputStreamReader = new this.InputStreamReader(
        new this.FileInputStream(file),
        charset
      )
      let bufferedReader = new this.BufferedReader(inputStreamReader)

      let line = ''
      while ((line = bufferedReader.readLine()) != null) {
        if (line) list.push(line)
      }

      bufferedReader.close()
      inputStreamReader.close()
    } catch (e) {
      console.error('读取日志失败=>', e)
      // 确保资源关闭
      if (bufferedReader) bufferedReader.close()
      if (inputStreamReader) inputStreamReader.close()
    }
    return list
  },

  // 获取设备剩余存储空间的方法
  getSystemStorage: function () {
    const files = this.Environment.getDataDirectory()
    const statFs = new this.StatFs(files.getPath())
    const blockAva = parseFloat(statFs.getAvailableBlocks())
    const blockSize = parseFloat(statFs.getBlockSize())
    const internalMemSize = blockSize * blockAva

    return {
      rawSize: internalMemSize, // 原始大小
      size: transformByteData(internalMemSize) // 格式化后的值
    }
  }
}

// 初始化日志系统
LogCat.init()
// #endif

// 非APP-PLUS平台的空实现
// #ifndef APP-PLUS
const LogCat = {}
// #endif

/**
 * 时间格式化函数
 * @param {string} [style] - 格式类型(可选)，默认为 'YYYY-MM-DD hh:mm:ss'
 *  可选值:
 *    - 'hh:mm:ss'        : 时:分:秒
 *    - 'YYYY-MM-DD'      : 年-月-日
 *    - 'YYYYMMDD'        : 年月日
 *    - 'YYYY-MM-DD hh:mm:ss' : 年-月-日 时:分:秒 (默认)
 *    - 'YYYYMMDDhhmmss'  : 年月日时分秒
 *    - 'YYYY'            : 年
 *    - 'MM'              : 月
 *    - 'DD'              : 日
 *    - 'getDay'          : 星期几(0-6)
 * @returns {string} 格式化后的时间字符串
 */
const getTime = (style = 'YYYY-MM-DD hh:mm:ss') => {
  const time = new Date()

  // 时间组件补零处理
  const pad = num => (num < 10 ? `0${num}` : num)
  const yyyy = time.getFullYear()
  const mm = pad(time.getMonth() + 1) // 月份从0开始
  const dd = pad(time.getDate())
  const h = pad(time.getHours())
  const m = pad(time.getMinutes())
  const s = pad(time.getSeconds())
  const z = time.getDay() // 星期几(0-6)

  // 格式映射表
  const formats = {
    'hh:mm:ss': `${h}:${m}:${s}`,
    'YYYY-MM-DD': `${yyyy}-${mm}-${dd}`,
    YYYYMMDD: `${yyyy}${mm}${dd}`,
    'YYYY-MM-DD hh:mm:ss': `${yyyy}-${mm}-${dd} ${h}:${m}:${s}`,
    YYYYMMDDhhmmss: `${yyyy}${mm}${dd}${h}${m}${s}`,
    YYYY: yyyy,
    MM: mm,
    DD: dd,
    getDay: z
  }

  return formats[style] || formats['YYYY-MM-DD hh:mm:ss']
}

/**
 * @description 转化字节数据
 * @param {*} data 表示要被转化的容量大小，以字节为单位
 * @param {*} digit 表示如果转换时出小数，四舍五入保留多少位 默认为2位小数
 * @returns
 */
const transformByteData = (data, digit = 2, extension = '') => {
  if (!data) return `0${extension}B`
  const c = 1024
  const e = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
  const i = Math.floor(Math.log(data) / Math.log(c))
  return (data / c ** i).toFixed(digit) + extension + e[i]
}

export default LogCat
